package com.atguigu.gmall.item.controller;


import com.atguigu.gmall.common.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

@RestController
public class HelloController {

    @Autowired
    StringRedisTemplate redisTemplate;
    ReentrantLock lock = new ReentrantLock();

//    @Qualifier("otherPool")
//    @Autowired
//    ThreadPoolExecutor otherPool;
//
//    @GetMapping("/close/pool")
//    public Result closeThreadpool(){
//        otherPool.shutdown();
//        //实时监控
//        return Result.ok();
//    }

    @Value("${server.port}")
    String port;

    //所有juc的锁都得有一个分布式版，才能正常工作
    //[redisson]：提供了所有锁的分布式版。其它功能
    CountDownLatch latch = new CountDownLatch(7);

    @GetMapping("/longzhu")
    public String longzhu(){
        latch.countDown();
        return "ok";
    }

    @GetMapping("/shenlong")
    public String shenlong() throws InterruptedException {
        latch.await();
        return "神龙.....";
    }


    //1w请求，加到1w
    @GetMapping("/incr")
    public Result increment2(){



        return Result.ok();
    }


    public Result increment() {

//        lock.lock();

//        lock.unlock();
        String uuid = UUID.randomUUID().toString();
        //阻塞式抢锁代码
        lock(uuid);
        //抢到走到这里
        incr();
        unlock(uuid);

        return Result.ok();
    }

    //juc、
    //锁：
    //公平锁【自己用队列维护（redis的List）】、非公平锁？
    //读写锁？[锁饥饿]==  邮戳锁  读数据加读锁，写数据就加写锁
    //并发：并发读？读读读：无锁   读写：写锁是排他锁、独占锁？
    // 写读读读读读写读读读读读写读读读读写读读读读读读读读读读读读写
    //闭锁？CountDownLatch
    //信号量.....

    //分布式情况 都得重新实现一遍



    private void unlock(String uuid) {
        String script ="if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                "then\n" +
                "    return redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end";
        redisTemplate.execute(new DefaultRedisScript<>(script,Long.class),
                Arrays.asList("lock"), uuid);
    }

    private void lock(String uuid) {
        while (!redisTemplate.opsForValue().setIfAbsent("lock", uuid,
                60, TimeUnit.SECONDS)){
            //进去。 一直抢不到
        }
    }

    private void incr() {
        System.out.println("===="+port);
        String hello = redisTemplate.opsForValue().get("hello");
        int i = Integer.parseInt(hello);
        i++;
        redisTemplate.opsForValue().set("hello", "" + i);
    }
}
